home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / MiscKit1.7.1 / MiscKit / Palettes / MiscTableScroll / MiscIntList.M < prev    next >
Encoding:
Text File  |  1996-02-11  |  9.4 KB  |  354 lines

  1. //=============================================================================
  2. //
  3. //        Copyright (C) 1995 by Paul S. McCarthy and Eric Sunshine.
  4. //                Written by Paul S. McCarthy and Eric Sunshine.
  5. //                            All Rights Reserved.
  6. //
  7. //        This notice may not be removed from this source code.
  8. //
  9. //        This object is included in the MiscKit by permission from the authors
  10. //        and its use is governed by the MiscKit license, found in the file
  11. //        "License.rtf" in the MiscKit distribution.    Please refer to that file
  12. //        for a list of all applicable permissions and restrictions.
  13. //        
  14. //=============================================================================
  15. //-----------------------------------------------------------------------------
  16. // MiscIntList.M
  17. //
  18. //        A dynamically sizable list of integers.
  19. //
  20. //-----------------------------------------------------------------------------
  21. //-----------------------------------------------------------------------------
  22. // $Id: MiscIntList.M,v 1.5 95/10/03 05:08:16 zarnuk Exp $
  23. // $Log:        MiscIntList.M,v $
  24. //    Revision 1.5  95/10/03    05:08:16  zarnuk
  25. //    Fixed compiler warning.
  26. //    
  27. //    Revision 1.4  95/10/03    04:57:41  sunshine
  28. //    Fixed -init so Storage is allocated from [self zone].  Added copyFromZone:,
  29. //    initFromString:, and addIntList:.
  30. //    
  31. //    Revision 1.3  95/10/03    03:56:44  sunshine
  32. //    Fixed bug where -readFromString: couldn't parse negative numbers.
  33. //    
  34. //    Revision 1.2  95/09/30    19:01:05  zarnuk
  35. //    Added sting read/write methods.     Added rawData method.
  36. //-----------------------------------------------------------------------------
  37. #import <misckit/MiscIntList.h>
  38.  
  39. extern "Objective-C" {
  40. #import <objc/Storage.h>
  41. }
  42.  
  43. extern "C" {
  44. #include <stdlib.h>
  45. #include <stdio.h>
  46. }
  47.  
  48. //-----------------------------------------------------------------------------
  49. // std_cmp
  50. //-----------------------------------------------------------------------------
  51. static int std_cmp( void*, int x, int y )
  52.     {
  53.     if (x < y)
  54.         return -1;
  55.     if (y > x)
  56.         return 1;
  57.     return 0;
  58.     }
  59.  
  60.  
  61. //-----------------------------------------------------------------------------
  62. // qsort_cmp
  63. //-----------------------------------------------------------------------------
  64. static MiscIntListCompareFunc cmp_func = 0;
  65. static void* cmp_data = 0;
  66. static int qsort_cmp( void const* px, void const* py )
  67.     {
  68.     return (*cmp_func)( cmp_data, *((int const*)px), *((int const*)py) );
  69.     }
  70.  
  71.  
  72. @implementation MiscIntList
  73.  
  74. //-----------------------------------------------------------------------------
  75. // init
  76. //-----------------------------------------------------------------------------
  77. - init
  78.     {
  79.     [super init];
  80.     array = [[Storage allocFromZone: [self zone]]
  81.                 initCount:0 elementSize:sizeof(int) description:"i"];
  82.     return self;
  83.     }
  84.  
  85.  
  86. //-----------------------------------------------------------------------------
  87. // initFromString:
  88. //-----------------------------------------------------------------------------
  89. - initFromString: (char const*) s
  90.     {
  91.     [self init];
  92.     [self readFromString:s];
  93.     return self;
  94.     }
  95.  
  96.  
  97. //-----------------------------------------------------------------------------
  98. // free
  99. //-----------------------------------------------------------------------------
  100. - free
  101.     {
  102.     [array free];
  103.     return [super free];
  104.     }
  105.  
  106.  
  107. //-----------------------------------------------------------------------------
  108. // copyFromZone:
  109. //-----------------------------------------------------------------------------
  110. - copyFromZone: (NXZone*) zone
  111.     {
  112.     MiscIntList* clone = [super copyFromZone:zone];
  113.     clone->array = [array copyFromZone:zone];
  114.     return clone;
  115.     }
  116.  
  117.  
  118. //-----------------------------------------------------------------------------
  119. // empty
  120. //-----------------------------------------------------------------------------
  121. - empty
  122.     {
  123.     [array empty];
  124.     return self;
  125.     }
  126.  
  127.  
  128. //-----------------------------------------------------------------------------
  129. // count
  130. //-----------------------------------------------------------------------------
  131. - (unsigned int) count
  132.     {
  133.     return [array count];
  134.     }
  135.  
  136.  
  137. //-----------------------------------------------------------------------------
  138. // intAt:
  139. //-----------------------------------------------------------------------------
  140. - (int) intAt: (unsigned int) pos
  141.     {
  142.     return (pos < [self count] ? (*(int*)[array elementAt:pos]) : 0);
  143.     }
  144.  
  145.  
  146. //-----------------------------------------------------------------------------
  147. // addInt:
  148. //-----------------------------------------------------------------------------
  149. - (void) addInt: (int) value
  150.     {
  151.     [self insertInt: value at: [self count]];
  152.     }
  153.  
  154.  
  155. //-----------------------------------------------------------------------------
  156. // addIntList:
  157. //-----------------------------------------------------------------------------
  158. - (void) addIntList: (MiscIntList*) list
  159.     {
  160.     if (list != 0)
  161.         {
  162.         unsigned int const lim = [list count];
  163.         for (unsigned int i = 0; i < lim; i++)
  164.             [self addInt: [list intAt:i]];
  165.         }
  166.     }
  167.  
  168.  
  169. //-----------------------------------------------------------------------------
  170. // insertInt:at:
  171. //-----------------------------------------------------------------------------
  172. - (void) insertInt: (int) value at: (unsigned int) pos
  173.     {
  174.     [array insertElement: &value at: pos];
  175.     }
  176.  
  177.  
  178. //-----------------------------------------------------------------------------
  179. // removeIntAt:
  180. //-----------------------------------------------------------------------------
  181. - (void) removeIntAt: (unsigned int) pos
  182.     {
  183.     [array removeElementAt: pos];
  184.     }
  185.  
  186.  
  187. //-----------------------------------------------------------------------------
  188. // replaceIntAt:with:
  189. //-----------------------------------------------------------------------------
  190. - (void) replaceIntAt: (unsigned int) pos with: (int) value
  191.     {
  192.     [array replaceElementAt:pos with:&value];
  193.     }
  194.  
  195.  
  196. //-----------------------------------------------------------------------------
  197. // sortUsing:data:
  198. //-----------------------------------------------------------------------------
  199. - (void) sortUsing:(MiscIntListCompareFunc)func data:(void*)data
  200.     {
  201.     unsigned int const N = [self count];
  202.     if (N > 1)
  203.         {
  204.         cmp_func = (func ? func : std_cmp);
  205.         cmp_data = data;
  206.         qsort( [array elementAt:0], N, sizeof(int), qsort_cmp );
  207.         }
  208.     }
  209.  
  210.  
  211. //-----------------------------------------------------------------------------
  212. // sort
  213. //-----------------------------------------------------------------------------
  214. - (void) sort
  215.     {
  216.     [self sortUsing:&std_cmp data:0];
  217.     }
  218.  
  219.  
  220. //-----------------------------------------------------------------------------
  221. // append_char
  222. //-----------------------------------------------------------------------------
  223. static void append_char( char c, char*& buff, int& buff_size, 
  224.                         int& len, BOOL can_expand )
  225.     {
  226.     if (buff != 0)
  227.         {
  228.         if (len >= buff_size)
  229.             if (!can_expand)
  230.                 buff = 0;
  231.             else
  232.                 {
  233.                 buff_size <<= 1;        // Double the size.
  234.                 buff = (char*) realloc( buff, buff_size );
  235.                 }
  236.         if (buff != 0)
  237.             buff[ len++ ] = c;
  238.         }
  239.     }
  240.  
  241.  
  242. //-----------------------------------------------------------------------------
  243. // append_int
  244. //-----------------------------------------------------------------------------
  245. static void append_int( int x, char*& buff, int& buff_size, 
  246.                         int& len, BOOL can_expand )
  247.     {
  248.     char tmp[ 64 ];
  249.     sprintf( tmp, "%d", x );
  250.     for (char const* t = tmp;  *t != 0 && buff != 0;  t++)
  251.         append_char( *t, buff, buff_size, len, can_expand );
  252.     }
  253.  
  254.  
  255. //-----------------------------------------------------------------------------
  256. // - writeToString:size:canExpand:
  257. //-----------------------------------------------------------------------------
  258. - (char*) writeToString: (char*) buff size: (int) buff_size
  259.         canExpand:(BOOL) can_expand
  260.     {
  261.     int const START_SIZE = 32;
  262.     int i,x,len;
  263.     int const lim = [self count];
  264.  
  265.     if ((buff == 0 || buff_size == 0) && can_expand)
  266.         {
  267.         buff = (char*) malloc( START_SIZE );
  268.         buff_size = START_SIZE;
  269.         }
  270.  
  271.     if (buff_size == 0)
  272.         buff = 0;
  273.  
  274.     len = 0;
  275.     for (i = 0;     buff != 0 && i < lim;    i++)
  276.         {
  277.         x = [self intAt:i];
  278.         if (i > 0)
  279.             append_char( ' ', buff, buff_size, len, can_expand );
  280.         append_int( x, buff, buff_size, len, can_expand );
  281.         }
  282.  
  283.     append_char( '\0', buff, buff_size, len, can_expand );
  284.  
  285.     return buff;
  286.     }
  287.  
  288.  
  289. //-----------------------------------------------------------------------------
  290. // - writeToString:size:
  291. //-----------------------------------------------------------------------------
  292. - (char*) writeToString: (char*) buff size: (int) buff_size
  293.     {
  294.     return [self writeToString:buff size:buff_size canExpand:NO];
  295.     }
  296.  
  297.  
  298. //-----------------------------------------------------------------------------
  299. // writeToString
  300. //-----------------------------------------------------------------------------
  301. - (char*) writeToString
  302.     {
  303.     return [self writeToString:0 size:0 canExpand:YES];
  304.     }
  305.  
  306.  
  307. //-----------------------------------------------------------------------------
  308. // readFromString:
  309. //-----------------------------------------------------------------------------
  310. - (int) readFromString: (char const*) s
  311.     {
  312.     [self empty];
  313.     if (s != 0)
  314.         {
  315.         while (*s != 0)
  316.             {
  317.             while (*s != 0 && *s != '-' && (*s < '0' || '9' < *s))
  318.                 s++;
  319.  
  320.             BOOL is_neg = NO;
  321.             if (*s == '-')
  322.                 {
  323.                 is_neg = YES;
  324.                 s++;
  325.                 }
  326.  
  327.             if ('0' <= *s && *s <= '9')
  328.                 {
  329.                 int x = 0;
  330.                 do    {
  331.                     x = x * 10 + *s - '0';
  332.                     s++;
  333.                     }
  334.                 while ('0' <= *s && *s <= '9');
  335.                 [self addInt: (is_neg ? -x : x)];
  336.                 }
  337.             }
  338.         }
  339.     return [self count];
  340.     }
  341.  
  342.  
  343. //-----------------------------------------------------------------------------
  344. // rawData
  345. //-----------------------------------------------------------------------------
  346. - (int const*) rawData
  347.     {
  348.     if ([self count] == 0)
  349.         return 0;
  350.     return (int const*) [array elementAt: 0];
  351.     }
  352.  
  353. @end
  354.